package org.lqfan.service.impl;

import org.lqfan.dao.ItemDOMapper;
import org.lqfan.dao.ItemStockDOMapper;
import org.lqfan.dataobject.ItemDO;
import org.lqfan.dataobject.ItemStockDO;
import org.lqfan.error.BusinessException;
import org.lqfan.error.EmBusinessError;
import org.lqfan.service.ItemService;
import org.lqfan.service.model.ItemModel;
import org.lqfan.validator.ValidationResult;
import org.lqfan.validator.ValidatorImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ItemServiceImpl implements ItemService {

    @Autowired
    private ValidatorImpl validatorImpl;

    @Autowired
    private ItemDOMapper itemDOMapper;

    @Autowired
    private ItemStockDOMapper itemStockDOMapper;

    //创建商品
    @Override
    @Transactional
    public ItemModel createItem(ItemModel itemModel) throws BusinessException {
        //入参校验
        ValidationResult validate = validatorImpl.validate(itemModel);
        if(validate.isHasErrors()){
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, validate.getErrMsg());
        }

        //itemModel -> itemDO
        ItemDO itemDO = convertItemDOFromItemModel(itemModel);
        System.out.println(itemDO.getDescription());
        //写入数据库
        itemDOMapper.insertSelective(itemDO);
        itemModel.setId(itemDO.getId());

        ItemStockDO itemStockDO = convertItemStockDOFromItemModel(itemModel);
        itemStockDOMapper.insertSelective(itemStockDO);

        //返回创建完成的对象
        ItemModel item = this.getItemById(itemModel.getId());
        System.out.println(item.getDescription());
        return item;
    }

    //根据商品id获取商品详情
    @Override
    public ItemModel getItemById(Integer id) {
        ItemDO itemDO = itemDOMapper.selectByPrimaryKey(id);
        if(itemDO == null) {
            return null;
        }
        ItemModel itemModel = convertItemModelFromItemDO(itemDO);

        ItemStockDO itemStockDO = itemStockDOMapper.selectByItemId(itemModel.getId());
        itemModel.setStock(itemStockDO.getStock());

        return itemModel;
    }

    @Override
    public List<ItemModel> getListItem() {
        List<ItemDO> itemDOList = itemDOMapper.selectListItem();

        if(itemDOList == null || itemDOList.size() <= 0) {
            return null;
        }

        //使用java8 的stream api
        List<ItemModel> itemModelList = itemDOList.stream().map(itemDO -> {
            ItemModel itemModel = this.convertItemModelFromItemDO(itemDO);
            ItemStockDO itemStockDO = itemStockDOMapper.selectByItemId(itemDO.getId());
            itemModel.setStock(itemStockDO.getStock());

            return itemModel;
        }).collect(Collectors.toList());

        return itemModelList;
    }

    @Override
    public boolean decreaseStock(Integer itemId, Integer amount) {
        //innoDB存储引擎，对于UPDATE、DELETE和INSERT语句，InnoDB会自动给涉及数据集加锁（排他锁X）
        int result = itemStockDOMapper.decreaseStock(itemId, amount);

        //result 是SQL语句返回的受影响的行数
        if(result > 0){
            //更新库存成功
            return true;
        }else {
            return false;
        }
    }

    //itemModel -> itemDO
    private ItemDO convertItemDOFromItemModel(ItemModel itemModel) {
        if(itemModel == null) {
            return null;
        }
        ItemDO itemDO = new ItemDO();
        BeanUtils.copyProperties(itemModel, itemDO);
        itemDO.setPrice(itemModel.getPrice().doubleValue());

        return itemDO;
    }

    //itemModel -> itemStockDO
    private ItemStockDO convertItemStockDOFromItemModel(ItemModel itemModel) {
        if (itemModel == null) {
            return null;
        }
        ItemStockDO itemStockDO = new ItemStockDO();
        itemStockDO.setItemId(itemModel.getId());
        itemStockDO.setStock(itemModel.getStock());

        return itemStockDO;
    }

    //itemDO -> itemModel
    private ItemModel convertItemModelFromItemDO(ItemDO itemDO) {
        if(itemDO == null) {
            return null;
        }
        ItemModel itemModel = new ItemModel();
        BeanUtils.copyProperties(itemDO, itemModel);
        itemModel.setPrice(BigDecimal.valueOf(itemDO.getPrice()));

        return itemModel;
    }
}
